package com.ft.config;

import com.ft.model.enums.OrderStatusChangeEventEnum;
import com.ft.model.enums.OrderStatusEnum;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 状态机的 状态和事件都采用String类型表示
 * 原生提供的PersistStateMachineHandler(持久化状态机处理器)中的状态和事件都采用String类型表示
 * @author: zhangjianghua
 * @Date: 2018-10-09 17:02
 */
@Configuration
@EnableStateMachine
public class OrderStateMachineConfiguration extends StateMachineConfigurerAdapter<String, String> {

    /**
     * 配置状态
     * @param states
     * @throws Exception
     */
    @Override
    public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
        states
                .withStates()
                .initial(OrderStatusEnum.WAIT_PAYMENT.name())
                .states(Arrays.stream(OrderStatusEnum.values()).map(status->status.name()).collect(Collectors.toSet()));
    }
    /**
     * 配置状态转换事件关系
     * @param transitions
     * @throws Exception
     */
    @Override
    public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
        transitions
                .withExternal().source(OrderStatusEnum.WAIT_PAYMENT.name()).target(OrderStatusEnum.WAIT_DELIVER.name()).event(OrderStatusChangeEventEnum.PAYED.name())
                .and()
                .withExternal().source(OrderStatusEnum.WAIT_DELIVER.name()).target(OrderStatusEnum.WAIT_RECEIVE.name()).event(OrderStatusChangeEventEnum.DELIVERY.name())
                .and()
                .withExternal().source(OrderStatusEnum.WAIT_RECEIVE.name()).target(OrderStatusEnum.FINISH.name()).event(OrderStatusChangeEventEnum.RECEIVED.name());

    }
}
